home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 00 / 5 / DISK0050.ZIP / SDIR.ASM < prev    next >
Assembly Source File  |  1983-02-14  |  16KB  |  612 lines

  1.     TITLE    SDIR - SORTED DIRECTORY COMMAND, Version 2.1
  2.     PAGE    64,101                  ; JAN 1983
  3. COMMENT |
  4.     SDIR [d:][filename[.ext]] [options]
  5.      [filespec] same as for DIR command
  6.  
  7.      [options] * /A - List hidden files.
  8.            * /E - Without screen erase.
  9.            * /P - Pause when screen full.
  10.              /X - Sort by extension.
  11.              /S - Sort by size.
  12.              /D - Sort by date/time.
  13.              /N - Do not sort, original order.
  14.  
  15.        Default = *.* sorted by name.ext with screen erase.
  16.        * - Option may be combined with other options.
  17.  
  18.    This source file was created from an object file obtained
  19.  from Gene Plantz's BBS in Chicago. The original file name
  20.  was SD.HEX.  I then used DEBUG and CAPTURE to get the first
  21.  dis-assembly which  was then edited with WORDSTAR to create
  22.  a source that when assembled using MASM would duplicate the
  23.  original object file.
  24.    Comments have been added and I do hope they are helpful.
  25.  I have made several modifications to the first version and
  26.  am continuing to add comments.  This source file is an
  27.  excellent example for anyone wishing to learn 8086/8088
  28.  assembly language.  Use at your own risk and feel free to
  29.  share this file with your friends.
  30.    I certainly wish that John Chapman would publish his
  31.  source file.  His comments are sure to be more meaningful
  32.  than mine could ever be.  Some of the conversion routines
  33.  are very elegant, but difficult to understand.  As far as
  34.  I'm concerned, PRINTDD is magic.
  35.    Several modifications have been made.  They are:
  36.  
  37.     1. Filespecs are processed like DIR does.
  38.     2. No sort option was added. /N
  39.     3. Pause when screen full option added. /P
  40.     4. Number of files found is printed.
  41.  
  42.                     Ted Reuss
  43.                     Houston, TX
  44. |
  45.  
  46.     SUBTTL    EQUATES & STRUCTURES
  47.     PAGE
  48. IF1
  49. DOSCALL MACRO    FUNC,PARM1
  50. .xcref
  51. F_C    =    FUNC
  52. IFNB <PARM1>
  53. IF F_C EQ 2 OR (F_C GE 4 AND F_C LE 6) OR F_C EQ 14 OR F_C EQ 46
  54.     MOV    DL,PARM1
  55. ELSE
  56.     MOV    DX,OFFSET PARM1
  57. ENDIF
  58. ENDIF
  59.     MOV    AH,FUNC
  60.     INT    21H
  61. .cref
  62.     ENDM
  63. ENDIF
  64. .SALL    ;supress all macro expansions
  65. ;    PC-DOS INTERRUPT 21H FUNCTION CODES
  66. ;
  67. @CHROUT EQU    2    ;display char in DL
  68. @KEYIN    EQU    8    ;kybd input w/o echo
  69. @STROUT EQU    9    ;print string terminated with $
  70. @CKEYIN EQU    12    ;clr kybd bufr & do inp.func in AL
  71. @SRCH1    EQU    17    ;search for first dir entry
  72. @SRCH2    EQU    18    ;search for next dir entry
  73. @GETDSK EQU    25    ;get default disk drive
  74. @SETDTA EQU    26    ;set disk transfer addr
  75. @FATAD2 EQU    28    ;get FAT of drive # in DL
  76. @PARSEF EQU    41    ;parse filename
  77. @GETDTE EQU    42    ;get system date
  78. @GETTME EQU    44    ;get system time
  79.  
  80. CR    EQU    0DH    ;carriage return
  81. LF    EQU    0AH    ;line feed
  82. FCB_1    EQU    5CH    ;fcb for parameter 1
  83. PARAM_L EQU    80H    ;# characters in PARAM_B
  84. PARAM_B EQU    81H    ;DOS cmd parameter buffer.
  85.  
  86. ; PC-DOS packed date   <yyyyyyym mmmddddd>
  87. P_DTE    RECORD    P_YR:7,P_MO:4,P_DY:5
  88. ; PC-DOS packed time   <hhhhhmmm mmmsssss>
  89. P_TME    RECORD    P_HR:5,P_MI:6,P_2S:5
  90.  
  91. DIRNTRY STRUC        ;directory entry structure
  92. LNK    DW    0    ;ptr to next entry
  93. NAM    DB    8 DUP(0),'.' ;filename
  94. EXT    DB    3 DUP(0) ;extension
  95. TME    DW    0    ;time
  96. DTE    DW    0    ;date
  97. SZL    DW    0    ;low word of size
  98. SZH    DW    0    ;high word of size
  99. DIRNTRY ENDS
  100.  
  101.     SUBTTL    DATA AREA & INITIALIZATION
  102.     PAGE
  103. SDIR    SEGMENT PUBLIC 'CODE'
  104.     ASSUME    CS:SDIR,DS:SDIR,ES:SDIR
  105.     ORG    100H
  106. MAIN    PROC    FAR
  107.     JMP    STARTS
  108.  
  109. DIRLNK    DW    DIRBUF    ;ptr to next opening in DIRBUF
  110. C1LNK    DW    0    ;ptr to row 1, column 1
  111. C2LNK    DW    0    ;ptr to row 1, column 2
  112. NBRFILS DW    0    ;# of files or detail lines
  113. SRTFLG    DB    0    ;if = 0 then sort else no sort
  114. CLSFLG    DB    0    ;if = 0 then clear screen
  115. EXTFLG    DB    0    ;if <> 0 then sort by ext
  116. SIZFLG    DB    0    ;if <> 0 then sort by size
  117. DTEFLG    DB    0    ;if <> 0 then sort by date/time
  118. PSEFLG    DB    0    ;if <> 0 then pause if screen full
  119. LPERSCR EQU    25    ;Lines per screen
  120. LINCNT    DB    LPERSCR-4 ;Number of lines left
  121. PSEMSG    DB    'Strike a key when ready . . . $'
  122.  
  123. HDNG1    DB    'Sorted Disk Directory    Version 2.02     '
  124.     DB    'DRIVE '
  125. HDRVE    DB    '@:    Date '
  126. D_MM    DW    '00'            ;Month
  127.     DB    '/'
  128. D_DD    DW    '00'            ;Day
  129.     DB    '/'
  130. D_YY    DW    '00'            ;Year
  131.     DB    '  Time '
  132. T_HH    DW    '00'            ;Hours
  133.     DB    ':'
  134. T_MM    DW    '00'            ;Minutes
  135.     DB    CR,LF
  136. CRLF    DB    CR,LF,'$'
  137. HDNG2    DB    '--FILENAME--  -SIZE-  --LAST CHANGE--$'
  138.     DB    8 DUP(' ')
  139. SPACES    DB    '$'
  140. HDNG3    DB    ' File(s)',CR,LF,'$'
  141.  
  142.     SUBTTL    DISK TRANSFER AREA & FREE SPACE ENTRY DEFS
  143.     PAGE
  144.  
  145. XFCB    DB    -1,7 DUP(0),11 DUP('?'),25 DUP(0)
  146. ATTRIB    EQU    XFCB+6        ;file attribute
  147. DRVNBR    EQU    ATTRIB+1    ;drive # (1=A, 2=B, etc.)
  148.  
  149. DTA    DB    40 DUP(0)    ;Disk Transfer Area used
  150. FILNAME EQU    DTA+8        ;by SRCHDIR for the
  151. FILTIME EQU    DTA+30        ;directory search.
  152. FILSIZE EQU    DTA+36
  153.  
  154. FREESPC DW    0        ;Free space entry.
  155.     DB    '*FREE SPACE*',4 DUP(0)
  156. LOSIZE    DW    0        ;of free space
  157. HISIZE    DW    0        ;of free space
  158.  
  159.     SUBTTL    MAIN PROGRAM SECTION
  160.     PAGE
  161. STARTS:
  162.     PUSH    DS        ;Set up the
  163.     XOR    AX,AX        ; stack for a
  164.     PUSH    AX        ; return to DOS.
  165.     CALL    GETARGS     ;Process arguments
  166.     CALL    SRCHDIR     ;Search directory
  167.     CMP    SRTFLG,0    ;Check if any sort
  168.     JZ    A1        ; option selected.
  169.     CALL    LNKDIRB     ;Leave in original
  170.     JMP    SHORT A2    ; directory order.
  171. A1:    CALL    SRTDIRB     ;Sort by major key
  172. A2:    CALL    GETFREE     ;Get free space
  173.     CALL    SPLTLST     ;Set up for 2 columns
  174.     CALL    PRTHDNG     ;Print headings
  175.     CALL    PRTDRVR     ;Print detail lines
  176.     CALL    PRTNFLS     ;Print # of files
  177.     RET            ;Return to DOS
  178. MAIN    ENDP
  179.  
  180.     SUBTTL    GETARGS - PROCESS ARGUMENTS
  181.     PAGE
  182. GETARGS PROC    NEAR
  183.     MOV    SI,PARAM_B    ;point to cmd buffer
  184.     MOV    DI,OFFSET DRVNBR ;point to FCB
  185.     MOV    AL, 1111B    ;Select parse options
  186.     DOSCALL @PARSEF     ;Parse filename
  187.     CMP    BYTE PTR [DI],0 ;If <> 0 then
  188.     JNZ    B1        ; not default drive
  189.     DOSCALL @GETDSK     ;AL <- default disk
  190.     INC    AL        ;Increment drive #
  191.     STOSB            ;Save drive #
  192. B1:    MOV    SI,PARAM_L    ;SI <- ptr cmd length
  193.     MOV    CH,0
  194.     MOV    CL,[SI]     ;CL <- # chars in cmd
  195.     JCXZ    B10
  196. B2:    INC    SI        ;Point to next char
  197.     CMP    BYTE PTR [SI],'/'
  198.     JNZ    B8        ;If not a slash
  199.     MOV    AL,[SI+1]    ;AL <- option letter
  200.     AND    AL,0DFH     ;Force to upper-case
  201.     CMP    AL,'A'          ;Hidden & system files?
  202.     JNZ    B3        ;Nope, try next one.
  203.     MOV    BYTE PTR ATTRIB,2+4  ;Hidden & system
  204. B3:    CMP    AL,'E'          ;Without screen erase?
  205.     JNZ    B4        ;Nope, try next one.
  206.     MOV    CLSFLG,AL
  207. B4:    CMP    AL,'S'          ;Sort by size?
  208.     JNZ    B5        ;Nope, try next one.
  209.     MOV    SIZFLG,AL
  210. B5:    CMP    AL,'D'          ;Sort by date/time?
  211.     JNZ    B6        ;Nope, try next one.
  212.     MOV    DTEFLG,AL
  213. B6:    CMP    AL,'X'          ;Sort by extension?
  214.     JNZ    B7        ;Nope, try next one.
  215.     MOV    EXTFLG,AL
  216. B7:    CMP    AL,'N'          ;Original order?
  217.     JNZ    B8        ;Nope, try next one.
  218.     MOV    SRTFLG,AL
  219. B8:    CMP    AL,'P'          ;Pause when screen full?
  220.     JNZ    B9        ;Nope, try next one.
  221.     MOV    PSEFLG,AL
  222. B9:    LOOP    B2        ;Test for another param.
  223. B10:    RET
  224. GETARGS ENDP
  225.  
  226.     SUBTTL    SRCHDIR - SEARCH DIRECTORY
  227.     PAGE
  228. SRCHDIR PROC    NEAR
  229.     DOSCALL @SETDTA,DTA    ;Set DTA for dir. search
  230.     DOSCALL @SRCH1,XFCB    ;First call to search dir.
  231. C1:    OR    AL,AL
  232.     JNZ    C2        ;Not found, quit looking.
  233.     MOV    BX,DIRLNK    ;BX <- base of DIRBUF
  234.     LEA    DI,[BX].NAM
  235.     MOV    SI,OFFSET FILNAME
  236.     MOV    CX,SIZE NAM
  237.     CLD
  238.     REPZ    MOVSB        ;Move filename to DIRBUF
  239.     MOV    BYTE PTR [DI],'.' ; Store a period
  240.     INC    DI
  241.     MOV    CX,SIZE EXT
  242.     REPZ    MOVSB        ;Move ext to DIRBUF
  243.     MOV    SI,OFFSET FILTIME
  244.     MOVSW            ;Move time to DIRBUF
  245.     MOVSW            ;Move date to DIRBUF
  246.     MOV    SI,OFFSET FILSIZE
  247.     MOVSW            ;Move size to DIRBUF
  248.     MOVSW
  249.     ADD    BX,SIZE DIRNTRY ;Point to next entry
  250.     MOV    DIRLNK,BX    ;Save ptr
  251.     INC    NBRFILS     ;Increment file count
  252.     DOSCALL @SRCH2,XFCB    ;Search for next file
  253.     JMP    C1        ;Loop for next one
  254. C2:    RET
  255. SRCHDIR ENDP
  256.  
  257.     SUBTTL    SRTDIRB - SORTS ENTRIES IN DIRBUF
  258.     PAGE
  259. SRTDIRB PROC    NEAR    ;Sorts directory entries in DIRBUF
  260.     MOV    DI,OFFSET DIRBUF ;Point to DIRBUF
  261. D1:    CMP    DI,DIRLNK    ;Are there anymore?
  262.     JNC    D8        ;NO, exit
  263.     MOV    SI,OFFSET C1LNK ;Start with column 1 ptr
  264. D2:    MOV    BX,SI
  265.     MOV    SI,[BX]     ;SI<-ptr to next entry
  266.     OR    SI,SI
  267.     JZ    D7        ;if link=0
  268.     MOV    AX,SI
  269.     MOV    DX,DI
  270.     XOR    CL,CL        ;CL <- 0
  271.     CMP    CL,SIZFLG
  272.     JNZ    D5        ;If sort by size
  273.     CMP    CL,DTEFLG
  274.     JNZ    D4        ;If sort by date/time
  275.     CMP    CL,EXTFLG
  276.     JNZ    D3        ;If sort by ext
  277.     LEA    SI,[SI].NAM
  278.     LEA    DI,[DI].NAM
  279.     MOV    CX,1+SIZE NAM+SIZE EXT    ;# of bytes
  280.     JMP    SHORT D6
  281. D3:    LEA    SI,[SI].EXT    ;Sort by extension
  282.     LEA    DI,[DI].EXT
  283.     MOV    CX,SIZE EXT    ;# of bytes
  284.     JMP    SHORT D6
  285. D4:    LEA    SI,[SI].DTE    ;Sort by date/time
  286.     LEA    DI,[DI].DTE
  287.     MOV    CX,2        ;# of words
  288.     STD
  289.     REPZ    CMPSW
  290.     MOV    DI,DX
  291.     MOV    SI,AX
  292.     JBE    D2
  293.     JMP    SHORT D7
  294. D5:    LEA    SI,[SI].SZH    ;Sort by size
  295.     LEA    DI,[DI].SZH
  296.     MOV    CX,2        ;# of words
  297.     STD
  298.     REPZ    CMPSW
  299.     MOV    DI,DX
  300.     MOV    SI,AX
  301.     JBE    D2
  302.     JMP    SHORT D7
  303. D6:    CLD            ;Sort by name.ext
  304.     REPZ    CMPSB
  305.     MOV    DI,DX
  306.     MOV    SI,AX
  307.     JBE    D2
  308. D7:    MOV    [DI],SI
  309.     MOV    [BX],DI
  310.     ADD    DI,SIZE DIRNTRY ;Point to next entry
  311.     JMP    D1
  312. D8:    RET
  313. SRTDIRB ENDP
  314.  
  315.     SUBTTL
  316.     PAGE
  317. ; LNKDIRB - LINKS ENTRIES IN DIRBUF
  318.  
  319. LNKDIRB PROC    NEAR        ;LINK ENTRIES IN DIRBUF
  320.     MOV    DI,OFFSET DIRBUF
  321.     MOV    C1LNK,DI       ;Point to 1st entry
  322.     MOV    CX,NBRFILS    ;Set loop counter
  323.     DEC    CX
  324. LNK1:    MOV    BX,DI
  325.     ADD    DI,SIZE DIRNTRY ;Offset to next entry
  326.     MOV    [BX],DI     ;Store ptr
  327.     LOOP    LNK1        ;Link next entry
  328.     MOV    [DI],CX     ;Last ptr <- null
  329.     RET
  330. LNKDIRB ENDP
  331.  
  332. ; SPLTLST - SPLITS LINKED LIST IN HALF
  333.  
  334. SPLTLST PROC    NEAR
  335.     MOV    CX,NBRFILS    ;Get # of entries
  336.     SAR    CX,1        ; and divide by 2
  337.     JZ    F2        ;if NBRFILS < 2
  338.     ADC    CL,0        ;Account for odd #
  339.     MOV    BX,OFFSET C1LNK
  340. F1:    MOV    BX,[BX]     ;Chain thru list to
  341.     LOOP    F1        ; last row of column 1.
  342.     MOV    AX,[BX]     ;Get ptr to 1st row of col 2
  343.     MOV    C2LNK,AX    ; C2LNK <- R1,C2 ptr
  344.     MOV    [BX],CX     ;Last row of col 1 <- null
  345. F2:    RET
  346. SPLTLST ENDP
  347.  
  348.     SUBTTL    GETFREE - GET DISK FREE SPACE
  349.     PAGE
  350. GETFREE PROC    NEAR        ;cluster = allocation unit
  351.     MOV    DL,DRVNBR    ;Get drive #
  352.     PUSH    DS        ;Save DS
  353.     DOSCALL @FATAD2     ;Get FAT info from DOS
  354.     MOV    AH,0        ;AL = sector size
  355.     XCHG    CX,DX        ;Sector size times the
  356.     MUL    DX        ; # sectors/cluster
  357.     PUSH    AX        ;Save cluster size
  358.     XOR    AX,AX        ;Unused clusters = 0
  359.     MOV    SI,2        ;Skip first 3 clusters
  360. E1:    MOV    DI,SI        ;DI <- cluster #
  361.     SHR    DI,1        ;Divide cluster number
  362.     ADD    DI,SI        ; by 1.5
  363.     MOV    DI,[BX+DI]    ;Fetch from FAT
  364.     TEST    SI,1        ;Test if even or odd
  365.     JZ    E2        ;If even then skip
  366.     SHR    DI,1        ; else if odd
  367.     SHR    DI,1        ;  right justify the
  368.     SHR    DI,1        ;  cluster number.
  369.     SHR    DI,1
  370. E2:    AND    DI,0FFFH    ;Mask the low 12 bits
  371.     JNZ    E3        ;If not 0 then skip, else
  372.     INC    AX        ; increment counter.
  373. E3:    INC    SI        ;Point to next cluster
  374.     LOOP    E1        ; and go check it.
  375.     POP    CX        ;Get cluster size, times
  376.     MUL    CX        ;  # of free clusters
  377.     POP    DS        ;Restore DS
  378.     MOV    LOSIZE,AX    ;Save the 32 bit
  379.     MOV    HISIZE,DX    ; binary free space
  380.     MOV    BX,C1LNK    ;Insert FREESPC in
  381.     MOV    DI,OFFSET FREESPC ;first position
  382.     MOV    [DI],BX     ; of linked list of
  383.     MOV    C1LNK,DI    ; directory entries.
  384.     INC    NBRFILS     ;Bump # of entries
  385.     RET
  386. GETFREE ENDP
  387.  
  388.     SUBTTL    PRTHDNG - PRINT HEADINGS
  389.     PAGE
  390. PRTHDNG PROC    NEAR
  391.     MOV    AL,CLSFLG
  392.     OR    AL,AL
  393.     JNZ    G1        ;If not erase screen
  394.     SUB    CX,CX
  395.     MOV    DX,24*256+79    ;row=24 col=79
  396.     MOV    BH,7        ;Video mode
  397.     MOV    AX,0600H
  398.     INT    10H        ;BIOS video call
  399.     SUB    DX,DX
  400.     MOV    AH,2        ;Clear screen
  401.     MOV    BH,0
  402.     INT    10H        ;BIOS video call
  403. G1:    MOV    AL,DRVNBR    ;Get drive #
  404.     ADD    HDRVE,AL    ;Convert to ascii
  405.     DOSCALL @GETDTE ; CX<-year, DH<-month, DL<-day
  406.     MOV    AL,DH
  407.     AAM
  408.     XCHG    AL,AH
  409.     OR    D_MM,AX     ;Fold into month
  410.     MOV    AL,DL
  411.     AAM
  412.     XCHG    AL,AH
  413.     OR    D_DD,AX     ;Fold into day
  414.     MOV    AX,CX
  415.     SUB    AX,1900
  416.     AAM
  417.     XCHG    AL,AH
  418.     OR    D_YY,AX     ;Fold into year
  419.     DOSCALL @GETTME ; CH<-hours, CL<-minutes
  420.     MOV    AL,CH        ;AL<-binary hours
  421.     AAM            ;Convert AL to two
  422.     XCHG    AL,AH        ; BCD digits in AX.
  423.     OR    T_HH,AX     ;Fold into hours
  424.     MOV    AL,CL        ;AL<-binary minutes
  425.     AAM            ;Convert AL to two
  426.     XCHG    AL,AH        ; BCD digits in AX.
  427.     OR    T_MM,AX     ;Fold into minutes
  428.     DOSCALL @STROUT,HDNG1    ;Print main heading
  429.     DOSCALL @STROUT,HDNG2    ;Print column 1 heading
  430.     CMP    WORD PTR C2LNK,0
  431.     JZ    G2        ;If not 2 columns
  432.     DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
  433.     DOSCALL @STROUT,HDNG2    ;Print column 2 heading
  434. G2:    DOSCALL @STROUT,CRLF    ;Start a new line
  435.     RET
  436. PRTHDNG ENDP
  437.  
  438.     SUBTTL    PRINT DETAIL LINES
  439.     PAGE
  440. PRTDRVR PROC    NEAR        ;Driver routine
  441.     MOV    BX,C1LNK
  442.     OR    BX,BX        ;more to print?
  443.     JZ    H2        ; no, return
  444.     MOV    AX,[BX]
  445.     MOV    C1LNK,AX
  446.     CALL    PRTDTL        ;print column one
  447.     MOV    BX,C2LNK
  448.     OR    BX,BX
  449.     JZ    H1        ;If no column 2 entry
  450.     DOSCALL @STROUT,SPACES-5 ;print 5 spaces
  451.     MOV    AX,[BX]
  452.     MOV    C2LNK,AX
  453.     CALL    PRTDTL        ;print column two
  454. H1:    DOSCALL @STROUT,CRLF
  455.     CMP    PSEFLG,0    ;Check for pause option
  456.     JZ    PRTDRVR     ;Nope, continue
  457.     DEC    LINCNT        ;Decrement line counter
  458.     JNZ    PRTDRVR     ;If page not full?
  459.     MOV    LINCNT,LPERSCR-2 ;Reset to # lines/screen
  460.     DOSCALL @STROUT,PSEMSG    ;Display pause message.
  461.     MOV    AL,@KEYIN    ;Specify input function
  462.     DOSCALL @CKEYIN     ;Wait for key press
  463.     DOSCALL @STROUT,CRLF    ;Set to new line
  464.     JMP    PRTDRVR     ;Go do the next line
  465. H2:    RET
  466. PRTDRVR ENDP
  467.  
  468. PRTDTL    PROC    NEAR    ;Prints file.ext, size, date & time
  469.     MOV    CX,1+SIZE NAM+SIZE EXT
  470.     SUB    DI,DI        ;DI <- 0
  471. I1:    DOSCALL @CHROUT,[BX+DI].NAM
  472.     INC    DI        ;point to next char.
  473.     LOOP    I1        ;go do next char.
  474.     PUSH    BX        ;save entry base
  475.     MOV    SI,[BX].SZL    ;SI <- low size
  476.     MOV    DI,[BX].SZH    ;DI <- high size
  477.     CALL    PRINTDD     ;Print size
  478.     POP    BX        ;restore entry base
  479.     DOSCALL @STROUT,SPACES-2 ;print 2 spaces
  480.     MOV    AX,[BX].DTE    ;AX <- packed date
  481.     CALL    PRTDTE
  482.     DOSCALL @STROUT,SPACES-2 ;print 2 spaces
  483.     MOV    AX,[BX].TME    ;AX <- packed time
  484.     CALL    PRTTME
  485.     RET
  486. PRTDTL    ENDP
  487.  
  488.     SUBTTL    PRINTDD - PRINT A DOUBLE WORD IN DI:SI
  489.     PAGE
  490. PRINTDD PROC    NEAR    ;Prints a 32 bit integer in DI:SI
  491.     XOR    AX,AX        ;Zero out the
  492.     MOV    BX,AX        ; working
  493.     MOV    BP,AX        ; registers.
  494.     MOV    CX,32        ;# bits of precision
  495. J1:    SHL    SI,1
  496.     RCL    DI,1
  497.     XCHG    BP,AX
  498.     CALL    J6
  499.     XCHG    BP,AX
  500.     XCHG    BX,AX
  501.     CALL    J6
  502.     XCHG    BX,AX
  503.     ADC    AL,0
  504.     LOOP    J1
  505.     MOV    CX,1710H    ;5904 ?
  506.     MOV    AX,BX
  507.     CALL    J2
  508.     MOV    AX,BP
  509. J2:    PUSH    AX
  510.     MOV    DL,AH
  511.     CALL    J3
  512.     POP    DX
  513. J3:    MOV    DH,DL
  514.     SHR    DL,1        ;Move high
  515.     SHR    DL,1        ; nibble to
  516.     SHR    DL,1        ; the low
  517.     SHR    DL,1        ; position.
  518.     CALL    J4
  519.     MOV    DL,DH
  520. J4:    AND    DL,0FH        ;Mask low nibble
  521.     JZ    J5        ;If not zero
  522.     MOV    CL,0
  523. J5:    DEC    CH
  524.     AND    CL,CH
  525.     OR    DL,'0'          ;Fold in ASCII zero
  526.     SUB    DL,CL
  527.     DOSCALL @CHROUT     ;Print next digit
  528.     RET            ;Exit to caller
  529. PRINTDD ENDP
  530.  
  531. J6    PROC    NEAR
  532.     ADC    AL,AL
  533.     DAA
  534.     XCHG    AL,AH
  535.     ADC    AL,AL
  536.     DAA
  537.     XCHG    AL,AH
  538.     RET
  539. J6    ENDP
  540.  
  541.     SUBTTL    PRINT DATE, TIME & # FILES ROUTINES
  542.     PAGE
  543. PRTDTE    PROC    NEAR    ;Print packed date in AX as MM/DD/YY
  544.     OR    AX,AX
  545.     JNZ    K1        ;If date <> 0
  546.     DOSCALL @STROUT,SPACES-8 ;Print 8 spaces
  547.     RET
  548. K1:    PUSH    AX
  549.     AND    AX,MASK P_MO    ;Mask the month,
  550.     MOV    CL,P_MO     ; set shift count,
  551.     SHR    AX,CL        ; right justify, &
  552.     CALL    PRTBCD        ; print it.
  553.     DOSCALL @CHROUT,'/'
  554.     POP    AX
  555.     PUSH    AX
  556.     AND    AX,MASK P_DY    ;Mask the day &
  557.     CALL    PRTBCD        ; print it.
  558.     DOSCALL @CHROUT,'/'
  559.     POP    AX
  560.     AND    AX,MASK P_YR    ;Mask the year,
  561.     MOV    CL,P_YR     ; set shift count,
  562.     SHR    AX,CL        ; right justify,
  563.     ADD    AX,80        ; add in year bias, &
  564.                 ; print it.
  565. PRTBCD: AAM            ;Convert AL to BCD
  566.     OR    AX,'00'         ;Convert to ASCII
  567.     PUSH    AX
  568.     DOSCALL @CHROUT,AH    ;High order digit
  569.     POP    AX
  570.     DOSCALL @CHROUT,AL    ;Low order digit
  571.     RET
  572. PRTDTE    ENDP
  573.  
  574. PRTTME    PROC    NEAR    ;Print packed time in AX as HH:MM
  575.     OR    AX,AX
  576.     JNZ    L1
  577.     DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
  578.     RET
  579. L1:    PUSH    AX
  580.     AND    AX,MASK P_HR    ;Mask the hours,
  581.     MOV    CL,P_HR     ; set shift count,
  582.     SHR    AX,CL        ; right justify, &
  583.     CALL    PRTBCD        ; print it.
  584.     DOSCALL @CHROUT,':'
  585.     POP    AX
  586.     AND    AX,MASK P_MI    ;Mask the minutes,
  587.     MOV    CL,P_MI     ; set shift count,
  588.     SHR    AX,CL        ; right justify, &
  589.     CALL    PRTBCD        ; print it.
  590.     RET
  591. PRTTME    ENDP
  592.  
  593. PRTNFLS PROC    NEAR    ;print number of files
  594.     MOV    SI,NBRFILS    ;get # of files
  595.     DEC    SI        ;-1 for free space
  596.     XOR    DI,DI        ;zero high order
  597.     CALL    PRINTDD     ;Print # of files
  598.     DOSCALL @STROUT,HDNG3
  599.     RET
  600. PRTNFLS ENDP
  601.     EVEN
  602. DIRBUF    DIRNTRY <>    ;Buffer for directory entr
  603. ;
  604. ;
  605. ;SOMETHING IS MISSING AFTER THIS!!
  606. ;  I'VE FILLED IN THE TWO STATEMENTS BELOW.
  607. ;THERE MAY STILL BE BUGS.
  608. ;
  609. ;
  610. SDIR    ENDS
  611.         END     MAIN
  612.